/*
** list.c for zappy in /home/druart_p/Work/projet/zappy/zappy-2015-2014s-renard_g/serv-src
**
** Made by pierrick druart
** Login   <druart_p@epitech.net>
**
** Started on  Tue Jul 10 15:34:30 2012 pierrick druart
** Last update Tue Jul 10 15:34:33 2012 pierrick druart
*/

#include	<stdlib.h>

#include	"list.h"

static void	list_clear(struct s_list *this, void (*f)(void *))
{
  struct s_item	*cur;
  struct s_item	*save;

  if (this->len != 0)
  {
    cur = this->head;
    while (cur != NULL)
    {
      if (f != NULL)
	f(cur->content);
      save = cur;
      cur = cur->next;
      free(save);
    }
    this->head = NULL;
    this->tail = NULL;
    this->len = 0;
  }
}

static int	list_find(struct s_list *this, int (*f)(void *, void *),
    void *data)
{
  struct s_item	*cur;
  int		ret;

  cur = NULL;
  if (this->len == 0)
    return (0);
  if (f != NULL)
  {
    cur = this->head;
    while (cur != NULL)
    {
      if ((ret = f(cur->content, data)) != -1)
	return (ret);
      cur = cur->next;
    }
  }
  return (0);
}

static void	list_add_front(struct s_list *this, void *content)
{
  struct s_item	*item;

  if (this != NULL)
  {
    item = new_item_param(content);
    if (item != NULL)
    {
      item->prev = NULL;
      item->next = this->head;
      if (this->head != NULL)
	this->head->prev = item;
      if (this->tail == NULL)
	this->tail = item;
      this->head = item;
      this->len++;
    }
  }
}

static void	list_add_back(struct s_list *this, void *content)
{
  struct s_item	*item;

  if (this != NULL)
  {
    item = new_item_param(content);
    if (item != NULL)
    {
      item->next = NULL;
      item->prev = this->tail;
      if (this->tail != NULL)
	this->tail->next = item;
      if (this->head == NULL)
	this->head = item;
      this->tail = item;
      this->len++;
    }
  }
}

struct s_list	*new_list()
{
  t_list	*list;

  list = (t_list *)malloc(sizeof(*list));
  if (list != NULL)
  {
    list->len = 0;
    list->head = NULL;
    list->tail = NULL;
    list->add_back = &list_add_back;
    list->add_front = &list_add_front;
    list->find = &list_find;
    list->clear = &list_clear;
    list->foreach = &list_for_each;
    list->erase = &list_erase;
    list->pop = &list_pop;
  }
  return (list);
}
